package com.atguigu.gmall.rabbit.service;

import com.alibaba.fastjson.JSONObject;
import com.atguigu.gmall.rabbit.entity.GmallCorrelationData;
import org.springframework.amqp.rabbit.connection.CorrelationData;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

import java.util.Date;
import java.util.UUID;

/**
 * 统一发送MQ封装后的实现类
 */
@SuppressWarnings("all")//不要显示重复的代码的浪线警告
@Component
public class RabbitService {

    @Autowired
    private RabbitTemplate rabbitTemplate;
    @Autowired
    private RedisTemplate redisTemplate;

    //发送普通消息
    public boolean sendMessage(String exchange, String routingKey, Object msg) {
        //不正确
        //rabbitTemplate.convertAndSend(exchange,routingKey,msg);


        GmallCorrelationData correlationData = retryMessageData(exchange, routingKey, msg);
        //正确
        rabbitTemplate.convertAndSend(exchange, routingKey, msg, correlationData);
        return true;
    }

    private GmallCorrelationData retryMessageData(String exchange, String routingKey, Object msg) {
        //重新发送是的应答对象 交换机 routingKey mes
        GmallCorrelationData correlationData = new GmallCorrelationData();
        String uuid = UUID.randomUUID().toString();
        System.out.println("uuid:"+uuid);
        correlationData.setId(uuid);
        correlationData.setExchange(exchange);
        correlationData.setRoutingKey(routingKey);
        correlationData.setMessage(msg);

        //队列应答   不能接收到GmallCorrelationData  只能借助Redis保存GmallCorrelationData
        redisTemplate.opsForHash().put("rabbit_prefix" ,uuid ,
                JSONObject.toJSONString(correlationData));
        return correlationData;
    }

    //发送死信延迟消息
    public void sendDeadLetterMessage(String exchange, String routingKey, Object msg,int delayTime) {
        GmallCorrelationData correlationData = retryMessageData(exchange, routingKey, msg);
        //是延迟消息需要设置延迟的时间
        correlationData.setDelay(true);
        //设置延迟时间
        correlationData.setDelayTime(delayTime);
        //发延迟消息
        rabbitTemplate.convertAndSend(exchange,routingKey,msg,message -> {
            System.out.println("发送消息的时间："+ new Date());
            //设置过期时间，基于死信
            message.getMessageProperties().setExpiration(String.valueOf(delayTime*1000));//TTL字符串类型，单位是毫秒
            return message;
        },correlationData);
    }

    //发送延迟消息（基于延迟插件）
    public void sendDelayMessage(String exchange, String routingKey, Object msg,int delayTime) {

        //基本属性进行设置
        GmallCorrelationData correlationData = retryMessageData(exchange, routingKey, msg);
        //是延迟消息需要设置延迟的时间
        correlationData.setDelay(true);
        //设置延迟时间
        correlationData.setDelayTime(delayTime);
        //发延迟消息
        rabbitTemplate.convertAndSend(exchange,routingKey,msg,message -> {
            System.out.println("发送消息的时间："+ new Date());
            //设置延迟时间，基于插件
            message.getMessageProperties().setDelay(delayTime * 1000);
            return message;
        },correlationData);
    }


}
